﻿using System;
using Firefly.Framework.Components.Cameras;
using Firefly.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Firefly.Framework.Components.Sky
{
    public class PerlinClouds : DrawableComponent, IHasCamera
    {
        private PerlinCloudsShader _shader;

        public float CloudCover
        {
            get { return _shader.CloudCover; }
            set { _shader.CloudCover = value; }
        }
        public float CloudSharpness
        {
            get { return _shader.CloudSharpness; }
            set { _shader.CloudSharpness = value; }
        }
        public float InverseCloudVelocity
        {
            get { return _shader.InverseCloudVelocity; }
            set { _shader.InverseCloudVelocity = value; }
        }
        public float NumberOfTiles
        {
            get { return _shader.NumberOfTiles; }
            set { _shader.NumberOfTiles = value; }
        }
        public Vector4 SunlightColor
        {
            get { return _shader.SunlightColor; }
            set { _shader.SunlightColor = value; }
        }

        public PerlinClouds(Game game, ICamera camera)
            : base(game)
        {
            Camera = camera;
        }

        #region IHasContent Members

        public override void LoadContent()
        {
            _shader = new PerlinCloudsShader(this);
            _shader.LoadContent();
            _shader.CloudCover = 0.2f;
            _shader.CloudSharpness = 0.2f;
            _shader.InverseCloudVelocity = -10.0f;
            _shader.NumberOfTiles = 16; 
        }

        public override void UnloadContent()
        {
            _shader.Dispose();
        }

        #endregion

        #region IDrawable Members

        public override void Draw(GameTime gameTime)
        {
            if (Visible)
            {
                GraphicsService.Instance.RenderState.AlphaBlendEnable = true;
                GraphicsService.Instance.RenderState.SourceBlend = Blend.One;
                GraphicsService.Instance.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
                _shader.World = Matrix.CreateScale(40000.0f, 40000.0f, 100.0f) *
                    Matrix.CreateTranslation(new Vector3(0, 0, -900)) *
                    Matrix.CreateRotationX((float)Math.PI / 2.0f) *
                    Matrix.CreateTranslation(Camera.Position.X, Camera.Position.Y, Camera.Position.Z) *
                    Matrix.CreateTranslation(1f, -100f, 1f);
                _shader.View = Camera.View;
                _shader.Projection = Camera.Projection;
                _shader.Time = (float)gameTime.TotalGameTime.TotalSeconds;
                _shader.Draw(gameTime);
                GraphicsService.Instance.RenderState.AlphaBlendEnable = false;
            }
        }

        #endregion

        #region IHasCamera Members

        public ICamera Camera { get; set; }

        #endregion

        #region IDisposable Members

        ~PerlinClouds()
        {
            Dispose(false);
        }

        #endregion
    }
}
